package com.gitee.taotaojs.mybootsuper.mapper;

import org.apache.ibatis.mapping.MappedStatement;
import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;
import tk.mybatis.mapper.mapperhelper.SqlHelper;

import java.util.Set;

/**
 * @author hantao
 */
public class MyComProvider extends MapperTemplate {

    /** 常量提取 */
    public static final String IF_STR = "</if>";
    /** 常量提取 */
    public static final String FOR_EACH_STR = "</foreach>";

    public MyComProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
        super(mapperClass, mapperHelper);
    }

    @SuppressWarnings("checkstyle:MissingJavadocMethod")
    public String insertObjList(MappedStatement ms){
        Class<?> entityClass = getEntityClass(ms);
        Set<EntityColumn> columns = EntityHelper.getColumns(entityClass);
        //修改返回值类型为实体类型
        setResultType(ms, entityClass);
        StringBuilder sql = new StringBuilder();
        StringBuilder sqlTemp = new StringBuilder();

        sql.append("insert ");
        sql.append("<if test='isIgnore != null and isIgnore == ture'>");
        sql.append(" ignore ");
        sql.append("</if>");
        sql.append(" into ");
        sql.append(tableName(entityClass));
        sql.append("<trim prefix='(' suffixOverrides=',' suffix=')'>");
        for(EntityColumn column : columns){
            sql.append(column.getColumn() + ",");
            //如果数据列不为空，就添加该数据，如果数据列为空，就添加默认值
            sqlTemp.append("<if test='item." + column.getEntityField().getName() + " != null'>");
            sqlTemp.append("#{item." + column.getEntityField().getName() + "},");
            sqlTemp.append(IF_STR);
            sqlTemp.append("<if test='item." + column.getEntityField().getName() + " == null'>");
            sqlTemp.append("default,");
            sqlTemp.append(IF_STR);
        }
        sql.append("</trim> values ");
        sql.append("<foreach collection='mysql.list' index='index' item='item' separator=','>");

        sql.append("<trim prefix='(' suffixOverrides=',' suffix=')'>");
        /*.substring(0, sqlTemp.length()-1)*/
        sql.append(sqlTemp);
        sql.append("</trim>");
        sql.append(FOR_EACH_STR);

        return sql.toString();
    }

    @SuppressWarnings("checkstyle:MissingJavadocMethod")
    public String deleteObjList(MappedStatement ms){
        Class<?> entityClass = getEntityClass(ms);
        //修改返回值类型为实体类型
        setResultType(ms, entityClass);
        StringBuilder sql = new StringBuilder();

        sql.append("DELETE ");
        sql.append(" FROM " + tableName(entityClass));
        getWhereStr(sql, entityClass);
        return sql.toString();
    }

    @SuppressWarnings("checkstyle:MissingJavadocMethod")
    public String updateObjList(MappedStatement ms){
        Class<?> entityClass = getEntityClass(ms);
        Set<EntityColumn> columns = EntityHelper.getColumns(entityClass);
        //修改返回值类型为实体类型
        setResultType(ms, entityClass);
        StringBuilder sql = new StringBuilder();

        sql.append("UPDATE " + tableName(entityClass));
        sql.append("<trim prefix=' set ' suffixOverrides=','>");
        for(EntityColumn column : columns){
            String colName = column.getColumn();
            String fieldName = column.getEntityField().getName();

            sql.append("    <trim prefix='" + colName + " = case ' suffix='end,'>");
            sql.append("         <foreach collection='mysql.list' item='item' index='index'>");
            sql.append("             <if test='item." + fieldName + " != null'>");
            // and item." + fieldName + " != \"\"
            sql.append("                 when id=#{item.id} then #{item." + fieldName + "}");
            sql.append("             " + IF_STR);
            sql.append("             <if test='item." + fieldName + " == null'>");
            //表中原数据
            sql.append("                 when id=#{item.id} then " + colName);
            sql.append("             " + IF_STR);
            sql.append("         " + FOR_EACH_STR);
            sql.append("    </trim>");
        }
        sql.append("</trim>");
        sql.append("where id in ");
        sql.append("<foreach collection='mysql.list' index='index' item='item' separator=',' open='(' close=')'>");
        sql.append("#{item.id}");
        sql.append(FOR_EACH_STR);

        return sql.toString();
    }

    @SuppressWarnings("checkstyle:MissingJavadocMethod")
    public String selectObjList(MappedStatement ms){
        return selectObjMap(ms);
    }

    @SuppressWarnings("checkstyle:MissingJavadocMethod")
    public String selectObjMap(MappedStatement ms){
        Class<?> entityClass = getEntityClass(ms);
        //修改返回值类型为实体类型
        setResultType(ms, entityClass);
        StringBuilder sql = new StringBuilder();
        getSelectStr(sql, entityClass);
        getFromStr(sql, entityClass);
        getWhereStr(sql, entityClass);
        getGroupAndOrderStr(sql);
        return sql.toString();
    }

    /**
     * 通用select头
     * @param sql sql字符串
     * @param entityClass entityClass
     */
    private void getSelectStr(StringBuilder sql, Class<?> entityClass){
        sql.append(SqlHelper.selectAllColumns(entityClass));
        sql.append("<if test='mysql.select != null and mysql.select.length() > 0'>");
        sql.append(",${mysql.select}");
        sql.append(IF_STR);
    }

    /**
     * 通用from文本
     * @param sql sql字符串
     * @param entityClass entityClass
     */
    private void getFromStr(StringBuilder sql, Class<?> entityClass){
        sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));
        sql.append("<if test='mysql.from != null and mysql.from.length() > 0'>");
        sql.append(",${mysql.from}");
        sql.append(IF_STR);
        sql.append("<if test='mysql.join != null'>");
            sql.append("<if test='mysql.join.inner != null and mysql.join.inner.length() > 0'>");
                sql.append("<foreach collection='mysql.join.inner' item='dramaId' open='(' close=')' separator=','>");
                sql.append("inner join ${dramaId}");
                sql.append(FOR_EACH_STR);
            sql.append(IF_STR);
            sql.append("<if test='mysql.join.left != null and mysql.join.left.length() > 0'>");
                sql.append("<foreach collection='mysql.join.left' item='dramaId' open='(' close=')' separator=','>");
                sql.append("left join ${dramaId}");
                sql.append(FOR_EACH_STR);
            sql.append(IF_STR);
            sql.append("<if test='mysql.join.right != null and mysql.join.right.length() > 0'>");
                sql.append("<foreach collection='mysql.join.right' item='dramaId' open='(' close=')' separator=','>");
                sql.append("right join ${dramaId}");
                sql.append(FOR_EACH_STR);
            sql.append(IF_STR);
        sql.append(IF_STR);
    }

    /**
     * 通用where文本
     * @param sql sql字符串
     * @param entityClass 对象类型
     */
    private void getWhereStr(StringBuilder sql, Class<?> entityClass){

        sql.append("<where>");
        sql.append(" 1=1 ");
        //可兼容id批量增删改查，根据多个列名多个字段查询
        sql.append("<if test='mysql.idsMapList != null and mysql.idsMapList.size > 0'>");
            sql.append("<foreach collection='mysql.idsMapList' item='idsMap'>");
        //如果value不为空，且长度大于0
            sql.append("<if test='idsMap.value != null and idsMap.value.size > 0'>");
            sql.append(" and ");
        //如果列名不为空，且文字长度大于0
            sql.append("<if test='idsMap.key != null and idsMap.key.length() > 0'>");
            sql.append("${idsMap.key}");
            sql.append(IF_STR);
        //如果为null，则默认设置为id
            sql.append("<if test='idsMap.key == null or idsMap.key.length() == 0'>");
            sql.append(" id ");
            sql.append(IF_STR);
            sql.append(" in ");
        //开启循环value
            sql.append("<foreach collection='idsMap.value' item='dramaId' open='(' close=')' separator=','>");
            sql.append("#{dramaId}");
            sql.append(FOR_EACH_STR);
            sql.append(IF_STR);
            sql.append(FOR_EACH_STR);
        sql.append(IF_STR);
        //是否存在dataWhere条件集合
        sql.append("<if test='mysql.dataWhere != null and mysql.dataWhere.size > 0'>");
        sql.append("<foreach collection='mysql.dataWhere' item='dramaId'  separator=' '>");
        sql.append("<if test='dramaId.connection != null'>");
        sql.append(" ${dramaId.connection.code} ");
        sql.append(IF_STR);
        sql.append("<if test='dramaId.connection == null'>");
        sql.append(" and ");
        sql.append(IF_STR);
        sql.append(" ${dramaId.whereStr} ");
        sql.append(FOR_EACH_STR);
        sql.append(IF_STR);

        //需要删除/逻辑删除的id列表(可以被idsMapList取代)
        sql.append("<if test='mysql.deleteList != null and mysql.deleteList.size > 0'>");
        sql.append("and id in");
        sql.append("<foreach collection='mysql.deleteList' item='dramaId' open='(' close=')' separator=','>");
        sql.append("${dramaId}");
        sql.append(FOR_EACH_STR);
        sql.append(IF_STR);

        //获取entity对应的where语句
        getEntityWhereStr(sql, entityClass);

        sql.append("</where>");

    }

    /**
     * 通用分组和排序文本
     * @param sql sql字符串
     */
    private void getGroupAndOrderStr(StringBuilder sql){
        //group
        sql.append("<if test='mysql.group != null and mysql.group.length() > 0'>");
        sql.append(" group by ${mysql.group} ");
        sql.append(IF_STR);
        //order
        sql.append("<if test='mysql.order != null and mysql.order.size > 0'>");
        sql.append(" order by ");
        sql.append("<foreach collection='mysql.order' item='dramaId' separator=','>");
        sql.append("${dramaId.key} ${dramaId.value}");
        sql.append(FOR_EACH_STR);
        sql.append(IF_STR);
    }

    /**
     * 获取直接由实体类对象形成的where条件
     * @param sql
     * @param entityClass
     */
    @SuppressWarnings("checkstyle:MissingJavadocMethod")
    public void getEntityWhereStr(StringBuilder sql, Class<?> entityClass){
        Set<EntityColumn> columns = EntityHelper.getColumns(entityClass);
        sql.append("<if test='mysql.entity != null'>");
        sql.append(" and (1=1");
        //循环对象中所有属性
        for(EntityColumn column : columns) {
            String colName = column.getColumn();
            String fieldName = column.getEntityField().getName();
            sql.append("<if test='mysql.entity." + fieldName + " != null' >");
            sql.append(" and  " + colName + " = #{mysql.entity." + fieldName + "}");
            sql.append(IF_STR);
        }
        sql.append(")");
        sql.append(IF_STR);
    }



}
